#pragma once

#include "base_define.h"
#include "Lock.h"
#include "RefCounted.h"

namespace xBase
{
    template<typename T>
    class TxSingleton
    {
    public:
        static T* Instance();

    private:
        TxSingleton();
        virtual ~TxSingleton();

    private:
        static CxLock           m_oLock;
        static CScopedRefPtr<T> m_pInstance;

    private:
        TxSingleton(const TxSingleton& other);
        TxSingleton & operator = (const TxSingleton & other);
    };

    template<typename T>
    TxSingleton<T>::TxSingleton()
    {

    }

    template<typename T>
    TxSingleton<T>::~TxSingleton()
    {

    }

    template<typename T>
    CxLock TxSingleton<T>::m_oLock;

    template<typename T>
    CScopedRefPtr<T> TxSingleton<T>::m_pInstance;

    template<typename T>
    T* TxSingleton<T>::Instance()
    {
        if (0 == m_pInstance.get())
        {
            CxAutoLock oAutoLock(m_oLock);
            if (0 == m_pInstance.get())
            {
                m_pInstance.Reset(new T);
            }
        }
        return m_pInstance.get();
    }
}

#define DECLARE_SINGLETON_CLASS(type)   \
    friend class xBase::TxSingleton<type>;